		TITLE	QUICK - Copyright (c) SLR Systems 1994

		INCLUDE	MACROS
		INCLUDE	SYMBOLS
		INCLUDE	MODULES
if	fg_segm
		INCLUDE	SEGMSYMS
endif

if	fg_pe
		INCLUDE	RESSTRUC
endif

		PUBLIC	TQUICK_NUMERIC,TQUICK_ALPHA,TQUICK_ALPHA_XREF


		.DATA

		EXTERNDEF	XR_CURNMOD_GINDEX:DWORD
		EXTERNDEF	FIRST_IMPMOD_GINDEX:DWORD,FIRST_MODULE_GINDEX:DWORD,FIRST_ENTRYNAME_GINDEX:DWORD
		EXTERNDEF	FIRST_RESNAME_GINDEX:DWORD,FIRST_EXTERNAL_GINDEX:DWORD,FIRST__IMP__GINDEX:DWORD

		EXTERNDEF	MODULE_GARRAY:STD_PTR_S,SYMBOL_GARRAY:STD_PTR_S,ENTRYNAME_GARRAY:STD_PTR_S,IMPNAME_GARRAY:STD_PTR_S
		EXTERNDEF	RESNAME_GARRAY:STD_PTR_S


		.CODE	PASS2_TEXT

		EXTERNDEF	GET_NEW_LOG_BLK:PROC,STORE_XREF_ENTRY:PROC


QEXCHANGE	MACRO

		MOV	EAX,[ESI]
		MOV	EBX,[EDI]
		MOV	[EDI],EAX
		MOV	[ESI],EBX

		ENDM


QUICK_VARS	STRUC

QN_SYMBOL_TEXT_BP	DB	SYMBOL_TEXT_SIZE DUP(?)

QAX_TO_DSSI_BP		DD	?
QAX_TO_ESDI_BP		DD	?
QAX_COMPARE_BP		DD	?
QAX_MOVE_TEXT_BP	DD	?
QDELTA_BP		DD	?
QLEFT_NUMBER_BP		DD	?
QRIGHT_NUMBER_BP	DD	?
Q_OS2_NUMBER_BP		DD	?
QLEFT_PTR_BP		DD	?
QRIGHT_PTR_BP		DD	?
QMIDDLE_PTR_BP		DD	?
QN_BUFFER_PTR_BP	DD	?
QN_SYMBOL_MODULE_BP	DD	?
QN_SYMBOL_HASH_BP	DD	?
QN_SYMBOL_LENGTH_BP	DD	?
QN_PTR_BP		DD	?

QUICK_VARS	ENDS


FIX	MACRO	X

X	EQU	([EBP-SIZE QUICK_VARS].(X&_BP))

	ENDM


FIX	QAX_TO_DSSI
FIX	QAX_TO_ESDI
FIX	QAX_COMPARE
FIX	QAX_MOVE_TEXT
FIX	QDELTA
FIX	QLEFT_NUMBER
FIX	QRIGHT_NUMBER
FIX	Q_OS2_NUMBER
FIX	QLEFT_PTR
FIX	QRIGHT_PTR
FIX	QMIDDLE_PTR
FIX	QN_BUFFER_PTR
FIX	QN_SYMBOL_MODULE
FIX	QN_SYMBOL_HASH
FIX	QN_SYMBOL_LENGTH
FIX	QN_SYMBOL_TEXT
FIX	QN_PTR


TQUICK_NUMERIC	PROC
		;
		;USE QUICKSORT ALGORITHM TO SORT SYMBOL TABLE IN NUMERIC
		;ORDER
		;
		;
		;FIRST COPY INDEXES TO ANOTHER AREA FOR EASY SORTING
		;
		PUSHM	EBP,EDI,ESI,EBX		;SAVE THAT STACK FRAME

		MOV	EBP,ESP
		ASSUME	EBP:PTR QUICK_VARS
                ;
                ; Adjust ESP in 4K increments
                ;
		SUB	ESP,SIZEOF QUICK_VARS - SYMBOL_TEXT_SIZE - 4
                PUSH	EBP
                SUB	ESP,SYMBOL_TEXT_SIZE/2 - 4
                PUSH	EBP
                SUB	ESP,SYMBOL_TEXT_SIZE/2 - 4
                PUSH	EBP

		MOV	QN_BUFFER_PTR,EAX
		CALL	QUICK_INIT

		CALL	QUICK_NUM

		MOV	ESP,EBP

		POPM	EBX,ESI,EDI,EBP

		RET

TQUICK_NUMERIC	ENDP


QUICK_NUMERIC_1	PROC	NEAR	PRIVATE

QUICK_2:
		;
		;JUST SORT THE TWO AND RETURN...
		;
		CALL	Q_SET_LEFT_BLOCK	;DS:SI
		CALL	Q_SET_RIGHT_BLOCK	;ES:DI
		JMP	QN_SORT2


QUICK3:
		POP	EAX
QUICK2_FINISH:
QUICK_DONE:

		RET

QUICK_NUM::
		;
		;OK BOYS, HERE GOES A QUICK-SORT IMPLEMENTATION...
		;
		;ESI IS LEFT SYMBOL #, EDI IS RIGHT SYMBOL #
		;
		MOV	ECX,EDI
QUICK_NUM_1:
		SUB	ECX,ESI
		JNA	QUICK_DONE	;RIGHT <= LEFT, QUIT
		;
		;WHAT ABOUT REAL SMALL CX ?
		;
		INC	ECX
		JZ	QUICK_DONE	;NO SYMBOLS AT ALL...

		CMP	ECX,2
		JZ	QUICK_2

		MOV	QDELTA,ECX

		SHR	ECX,1
		PUSH	ESI		;SAVE ORIGINAL LEFTY

		ADD	ECX,ESI		;HALF WAY IN BETWEEN...
		MOV	QRIGHT_NUMBER,EDI

		MOV	QLEFT_NUMBER,ESI
		CALL	Q_SET_LEFT_BLOCK	;DS:SI

		MOV	QLEFT_PTR,ESI
		CALL	Q_SET_RIGHT_BLOCK	;ES:DI

		MOV	QRIGHT_PTR,EDI
		CALL	Q_SET_MIDDLE_BLOCK	;ES:DI

		MOV	QMIDDLE_PTR,EDI
		;
		;DO THREE-SOME SORT
		;
		;IF LEFT>MIDDLE, XCHG LEFT&MIDDLE
		;
		CALL	QN_SORT2
		;
		;IF LEFT > RIGHT, XCHG LEFT&RIGHT
		;
		MOV	EDI,QRIGHT_PTR
		CALL	QN_SORT2
		;
		;LASTLY, IF MIDDLE > RIGHT, XCHG MIDDLE&RIGHT
		;
		MOV	ESI,QMIDDLE_PTR
		CALL	QN_SORT2

		CMP	QDELTA,3
		JZ	QUICK3
		;
		;NOW XCHG MIDDLE WITH RIGHT-1
		;
		CALL	DEC_RIGHT_ESDI

		QEXCHANGE

		MOV	EAX,QRIGHT_NUMBER	;SAVE RIGHTY
		;
		;DEFINE TEST SYMBOL FROM RIGHT END (ORIGINALLY FROM MIDDLE)
		;
		MOV	ESI,[EDI]		;GET RIGHT SYMBOL VALUE
		CONVERT	ESI,ESI,SYMBOL_GARRAY
		ASSUME	ESI:PTR SYMBOL_STRUCT

		PUSH	EAX

		MOV	EBX,[ESI]._S_OFFSET
		CALL	DEC_RIGHT_ESDI

		MOV	ECX,[ESI]._S_OS2_NUMBER	;SECTION INDEX AND SELECTOR NUM ARE SAME ADDRESS
		MOV	QRIGHT_PTR,EDI

		MOV	ESI,QLEFT_PTR
		ASSUME	ESI:NOTHING
		CALL	INC_LEFT_DSSI
		;
		;SCAN FROM LEFT UNTIL SOMETHING FOUND >= CX:BX
		;
		MOV	EDX,QLEFT_NUMBER
QNL_AGAIN:
QNL_LOOP:
		;
		;COMPARE LEFT SYMBOL
		;
		MOV	EDI,[ESI]			;GET NEXT INDEX
		ADD	ESI,4

		CONVERT	EDI,EDI,SYMBOL_GARRAY
		ASSUME	EDI:PTR SYMBOL_STRUCT

		MOV	EAX,[EDI]._S_OS2_NUMBER

		CMP	EAX,ECX				;IF OVERLAYS, THIS IS SECTION #
		JC	QNL_NEXT

		MOV	EAX,[EDI]._S_OFFSET
		JNZ	QNL_TRY_RIGHT

		CMP	EAX,EBX
		JNC	QNL_TRY_RIGHT
QNL_NEXT:
		LEA	EAX,[EDX+1]
		INC	EDX

		TEST	EAX,PAGE_SIZE/4 - 1
		JNZ	QNL_LOOP

		MOV	ESI,EDX
		CALL	Q_SET_LEFT_BLOCK

		JMP	QNL_LOOP


QNL_TRY_RIGHT:
		;
		;OOPS, CHANGE AND SCAN FROM OTHER DIRECTION
		;
		SUB	ESI,4
		MOV	EDI,QRIGHT_PTR
		ASSUME	EDI:NOTHING

		MOV	QLEFT_NUMBER,EDX
		MOV	EDX,QRIGHT_NUMBER

		MOV	QLEFT_PTR,ESI
		;
		;SCAN FROM RIGHT UNTIL SOMETHING FOUND <= CX:BX
		;
QNR_LOOP:
		MOV	ESI,[EDI]
		SUB	EDI,4

		CONVERT	ESI,ESI,SYMBOL_GARRAY
		ASSUME	ESI:PTR SYMBOL_STRUCT

		CMP	[ESI]._S_OS2_NUMBER,ECX		;IF OVERLAYS, THIS IS SECTION #
		JC	QNR_SWAP

		MOV	EAX,[ESI]._S_OFFSET
		JNZ	QNR_NEXT

		CMP	EAX,EBX
		JBE	QNR_SWAP
QNR_NEXT:
		MOV	EAX,EDX
		DEC	EDX

		TEST	EAX,PAGE_SIZE/4-1
		JNZ	QNR_LOOP

		MOV	EDI,EDX
		CALL	Q_SET_RIGHT_BLOCK

		JMP	QNR_LOOP


QNR_SWAP:
		;
		;SWAP INDEXES IN TABLE PLEASE
		;
		ADD	EDI,4
		MOV	ESI,QLEFT_PTR
		ASSUME	ESI:NOTHING

		MOV	QRIGHT_PTR,EDI
		MOV	EAX,QLEFT_NUMBER

		MOV	QRIGHT_NUMBER,EDX
		CMP	EAX,EDX

		MOV	EAX,[ESI]
		JNC	QN_DONE1		;SAME, CANNOT SWAP

		MOV	EDX,[EDI]
		MOV	[EDI],EAX

		MOV	[ESI],EDX
		;
		;MOVE BOTH POINTERS
		;
		CALL	DEC_RIGHT_ESDI

		MOV	QRIGHT_PTR,EDI
		CALL	INC_LEFT_DSSI

		MOV	EDX,QLEFT_NUMBER
		MOV	EAX,QRIGHT_NUMBER

		CMP	EAX,EDX
		JAE	QNL_AGAIN		;JUMP IF ANY LEFT
QN_DONE1:
		;
		;SWAP R+1 WITH ORIGINAL PTR...
		;
		POP	EDI		; THIS BECOMES i

		PUSH	EDI
		CALL	Q_SET_RIGHT_BLOCK

		QEXCHANGE		;SWAP THEM...
		;
		;DETERMINE WHICH HALF WILL BE PROCESSED...(WE WANT TO DO SMALLER HALF)
		;
		POP	ECX		;ORIGINAL RIGHTY - WHERE MIDDLE WAS STORED
		POP	EDX		;ORIGINAL LEFT

		INC	ECX
		MOV	EAX,QRIGHT_NUMBER

		MOV	EBX,ECX
		MOV	EDI,QLEFT_NUMBER

		SUB	EAX,EDX
		SUB	EBX,EDI

		CMP	EAX,EBX
		JC	QN_DONE2
		;
		;LETS SAY DO SECOND HALF FIRST
		;
		MOV	EAX,QRIGHT_NUMBER
		PUSH	EDX		;SAVE ORIGINAL LEFT NUMBER

		PUSH	EAX		;RIGHT TO USE THERE
		LEA	ESI,[EDI+1]

		MOV	EDI,ECX
		CALL	QUICK_NUM

		POPM	EDI,ESI

		MOV	ECX,EDI
		JMP	QUICK_NUM_1

QN_DONE2:
		;
		;LETS SAY DO FIRST HALF FIRST
		;
		INC	EDI
		MOV	ESI,EDX

		PUSH	EDI
		PUSH	ECX

		MOV	EDI,QRIGHT_NUMBER
		CALL	QUICK_NUM

		POPM	EDI,ESI

		MOV	ECX,EDI
		JMP	QUICK_NUM_1

QUICK_NUMERIC_1	ENDP


QUICK_INIT	PROC	NEAR	PRIVATE
		;
		;DO SETUP FOR A QUICKSORT
		;
		MOV	ECX,QN_BUFFER_PTR

		MOV	EAX,[ECX]
		ADD	ECX,4

		TEST	EAX,EAX			;ANY BLOCKS ALLOCATED?
		JNZ	L51$			;YES, PTRS ALREADY COPIED

		MOV	QN_PTR,ECX		;PLACE FOR BLOCK #'S
		CALL	QUICK_ANOTHER_BLOCK
		;
		;FIRST DO ALL IMPORTED SYMBOLS
		;
		OR	ECX,-1
		CALL	ADD_IMPORTS

		OR	ECX,-1
		CALL	ADD__IMPS
		;
		;NOW, DO ALL DEFINED SYMBOLS, BY MODULE
		;
		MOV	ESI,FIRST_MODULE_GINDEX
		XOR	ECX,ECX

		JMP	TEST_MODULE

MODULE_LOOP:
		CONVERT	ESI,ESI,MODULE_GARRAY
		ASSUME	ESI:PTR MODULE_STRUCT

		MOV	EAX,[ESI]._M_NEXT_MODULE_GINDEX
		MOV	ESI,[ESI]._M_FIRST_PUB_GINDEX

		PUSH	EAX
		JMP	TEST_PUBLIC

L265$:
		CALL	QUICK_ANOTHER_BLOCK

		JMP	L266$

PUBLIC_LOOP:
		MOV	EDX,ESI
		CONVERT	ESI,ESI,SYMBOL_GARRAY
		ASSUME	ESI:PTR SYMBOL_STRUCT
		MOV	EAX,DPTR [ESI]._S_NSYM_TYPE

		MOV	ECX,[ESI]._S_NEXT_SYM_GINDEX
		AND	AH,MASK S_SPACES

		PUSH	ECX
		JNZ	NEXT_PUBLIC

		CMP	EDI,PAGE_SIZE
		JZ	L265$
L266$:
		MOV	DPTR [EBX+EDI],EDX
		ADD	EDI,4
NEXT_PUBLIC:
		POP	ESI
TEST_PUBLIC:
		TEST	ESI,ESI
		JNZ	PUBLIC_LOOP

		POP	ESI
		JMP	TEST_MODULE

L405$:
		CALL	QUICK_ANOTHER_BLOCK

		JMP	L406$

TEST_MODULE:
		TEST	ESI,ESI
		JNZ	MODULE_LOOP
INIT_FINAL::
		CMP	EDI,PAGE_SIZE
		JZ	L405$
L406$:

		MOV	[EBX+EDI],ECX			;MARK END OF INDEXES WITH A ZERO
		ADD	EDI,4				;FOR TBLNEXT?
		;
		;NOW WE GET READY TO SORT!
		;
		ASSUME	ESI:NOTHING

		;
		;HOW MANY SYMBOLS ARE THERE?
		;
		MOV	ECX,QN_BUFFER_PTR
		MOV	EAX,QN_PTR

		SHR	EDI,2
		SUB	EAX,ECX

		SUB	EAX,8

		SHL	EAX,PAGE_BITS-4

		ADD	EAX,EDI

		MOV	[ECX],EAX
L51$:
		MOV	ECX,QN_BUFFER_PTR

		MOV	EDI,[ECX]
		;
		;EDI IS # OF SYMBOLS
		;
		XOR	EAX,EAX
		XOR	ESI,ESI			;SI (LEFT) SYMBOL IS 0

		DEC	EAX
		SUB	EDI,2			;DI (RIGHT) SYMBOL IS LAST_SYMBOL

		RET

QUICK_INIT	ENDP


if	fg_segm OR fg_pe

QUICK_ENTRY_INIT	PROC	NEAR
		;
		;DO SETUP FOR A QUICKSORT
		;
		MOV	EAX,QN_BUFFER_PTR

		ADD	EAX,4			;SKIP COUNT

		MOV	QN_PTR,EAX		;PLACE FOR BLOCK #'S
		CALL	QUICK_ANOTHER_BLOCK

		MOV	ESI,FIRST_ENTRYNAME_GINDEX
		JMP	TEST_ENTRY

ENTRY_LOOP:
		MOV	EDX,ESI
		CONVERT	ESI,ESI,ENT_GARRAY
		ASSUME	ESI:PTR ENT_STRUCT
		MOV	ECX,[ESI]._ENT_NEXT_ENT_GINDEX

		CMP	EDI,PAGE_SIZE
		JZ	L265$
L266$:
		MOV	[EBX+EDI],EDX
		ADD	EDI,4

		MOV	ESI,ECX

TEST_ENTRY:
		TEST	ESI,ESI
		JNZ	ENTRY_LOOP

		JMP	INIT_FINAL

L265$:
		CALL	QUICK_ANOTHER_BLOCK

		JMP	L266$

QUICK_ENTRY_INIT	ENDP

		ASSUME	ESI:NOTHING

endif


if	fg_pe

QUICK_RESNAMES_INIT	PROC	NEAR
		;
		;DO SETUP FOR A QUICKSORT
		;
		MOV	EAX,QN_BUFFER_PTR

		ADD	EAX,4

		MOV	QN_PTR,EAX	;PLACE FOR BLOCK #'S
		CALL	QUICK_ANOTHER_BLOCK

		MOV	ESI,FIRST_RESNAME_GINDEX
		JMP	TEST_RESNAME

RESNAME_LOOP:
		MOV	EDX,ESI
		CONVERT	ESI,ESI,RESNAME_GARRAY
		ASSUME	ESI:PTR RESNAME_STRUCT
		MOV	ECX,[ESI]._RN_NEXT_RN_GINDEX

		CMP	EDI,PAGE_SIZE
		JZ	L265$
L266$:
		MOV	[EBX+EDI],EDX
		ADD	EDI,4

		MOV	ESI,ECX

TEST_RESNAME:
		TEST	ESI,ESI
		JNZ	RESNAME_LOOP

		JMP	INIT_FINAL

L265$:
		CALL	QUICK_ANOTHER_BLOCK

		JMP	L266$


		ASSUME	ESI:NOTHING

QUICK_RESNAMES_INIT	ENDP

endif



QUICK_XREF_INIT	PROC	NEAR
		;
		;DO SETUP FOR A QUICKSORT
		;
		MOV	EAX,QN_BUFFER_PTR

		ADD	EAX,4

		MOV	QN_PTR,EAX		;PLACE FOR BLOCK #'S
		CALL	QUICK_ANOTHER_BLOCK

		;
		;ADD FROM FIRST_EXTERNAL_GINDEX, ALL MODULE PUBLICS, IMPORTED SYMBOLS IF REFERENCED, WEAK, LAZY, ALIAS TOO?
		;

		;
		;FIRST DO ALL IMPORTED SYMBOLS
		;
		XOR	ECX,ECX
		CALL	ADD_IMPORTS

		XOR	ECX,ECX
		CALL	ADD__IMPS
		;
		;NOW, DO ALL DEFINED SYMBOLS, BY MODULE
		;

		MOV	ESI,FIRST_MODULE_GINDEX
		XOR	ECX,ECX
		JMP	TEST_MODULE

MODULE_LOOP:
		CONVERT	ESI,ESI,MODULE_GARRAY
		ASSUME	ESI:PTR MODULE_STRUCT

		MOV	EAX,[ESI]._M_NEXT_MODULE_GINDEX
		MOV	ESI,[ESI]._M_FIRST_PUB_GINDEX

		PUSH	EAX
		JMP	TEST_PUBLIC

L265$:
		CALL	QUICK_ANOTHER_BLOCK

		JMP	L266$

PUBLIC_LOOP:
		MOV	EDX,ESI
		CONVERT	ESI,ESI,SYMBOL_GARRAY
		ASSUME	ESI:PTR SYMBOL_STRUCT
		MOV	EAX,DPTR [ESI]._S_NSYM_TYPE

		MOV	ECX,[ESI]._S_NEXT_SYM_GINDEX
		AND	AH,MASK S_SPACES

		PUSH	ECX
		JNZ	NEXT_PUBLIC

		CMP	EDI,PAGE_SIZE
		JZ	L265$
L266$:
		MOV	DPTR [EBX+EDI],EDX
		XOR	ECX,ECX

		ADD	EDI,4
		MOV	[ESI]._S_LAST_XREF,ECX
NEXT_PUBLIC:
		POP	ESI
TEST_PUBLIC:
		TEST	ESI,ESI
		JNZ	PUBLIC_LOOP

		POP	ESI
;		JMP	TEST_MODULE
TEST_MODULE:
		TEST	ESI,ESI
		JNZ	MODULE_LOOP
		;
		;ADD UNDEFINED SYMBOLS TO LIST
		;
		MOV	EAX,FIRST_EXTERNAL_GINDEX
		CALL	ADD_LIST_NOMOD

;		MOV	EAX,FIRST_ALIAS_DEFINED_GINDEX
;		CALL	ADD_LIST

;		MOV	EAX,FIRST_WEAK_DEFINED_GINDEX
;		CALL	ADD_LIST

;		MOV	EAX,FIRST_LAZY_DEFINED_GINDEX
;		CALL	ADD_LIST

		;
		;NOW WE GET READY TO SORT!
		;
		;HOW MANY SYMBOLS ARE THERE?
		;
		JMP	INIT_FINAL


		ASSUME	ESI:NOTHING

QUICK_XREF_INIT	ENDP


ADD_LIST_NOMOD	PROC
		;
		;EAX IS SYMBOL
		;
		MOV	ESI,EAX
		JMP	TEST_PUBLIC

PUBLIC_LOOP:
		MOV	EDX,ESI
		CONVERT	ESI,ESI,SYMBOL_GARRAY
		ASSUME	ESI:PTR SYMBOL_STRUCT
		MOV	EAX,DPTR [ESI]._S_NSYM_TYPE

		MOV	ECX,[ESI]._S_NEXT_SYM_GINDEX
		AND	AH,MASK S_SPACES

		PUSH	ECX
		JNZ	NEXT_PUBLIC

		CMP	EDI,PAGE_SIZE
		JZ	L265$
L266$:
		MOV	DPTR [EBX+EDI],EDX
		XOR	ECX,ECX

		ADD	EDI,4
		MOV	[ESI]._S_LAST_XREF,ECX

		MOV	[ESI]._S_DEFINING_MOD,ECX
NEXT_PUBLIC:
		POP	ESI
TEST_PUBLIC:
		TEST	ESI,ESI
		JNZ	PUBLIC_LOOP

		RET

L265$:
		CALL	QUICK_ANOTHER_BLOCK

		JMP	L266$

		ASSUME	ESI:NOTHING

ADD_LIST_NOMOD	ENDP


ADD_IMPORTS	PROC
		;
		;ECX IS XREF FLAG
		;
		MOV	ESI,FIRST_IMPMOD_GINDEX
		JMP	TEST_IMPMOD

IMPMOD_LOOP:
		CONVERT	ESI,ESI,IMPMOD_GARRAY
		ASSUME	ESI:PTR IMPMOD_STRUCT

		MOV	EDX,[ESI]._IMPM_NAME_SYM_GINDEX
		CALL	ADD_IMPORTED_SYMBOLS

		MOV	EDX,[ESI]._IMPM_ORD_SYM_GINDEX
		CALL	ADD_IMPORTED_SYMBOLS

		MOV	ESI,[ESI]._IMPM_NEXT_GINDEX
TEST_IMPMOD:
		TEST	ESI,ESI
		JNZ	IMPMOD_LOOP

		RET

ADD_IMPORTS	ENDP


ADD_IMPORTED_SYMBOLS	PROC
		;
		;
		;
		TEST	EDX,EDX
		JZ	L9$

		PUSH	ESI
		MOV	ESI,EDX

PUBLIC_LOOP:
		MOV	EDX,ESI
		CONVERT	ESI,ESI,SYMBOL_GARRAY
		ASSUME	ESI:PTR SYMBOL_STRUCT
		MOV	AL,[ESI]._S_REF_FLAGS

		TEST	AL,MASK S_SPACES
		JNZ	NEXT_PUBLIC

		TEST	AL,MASK S_REFERENCED
		JZ	NEXT_PUBLIC

		CMP	EDI,PAGE_SIZE
		JZ	L265$
L266$:
		MOV	DPTR [EBX+EDI],EDX
		ADD	EDI,4

		TEST	ECX,ECX
		JNZ	NEXT_PUBLIC

		MOV	[ESI]._S_LAST_XREF,ECX
NEXT_PUBLIC:
		MOV	ESI,[ESI]._S_NEXT_SYM_GINDEX
TEST_PUBLIC:
		TEST	ESI,ESI
		JNZ	PUBLIC_LOOP

		POP	ESI

L9$:
		RET


L265$:
		CALL	QUICK_ANOTHER_BLOCK

		JMP	L266$

		ASSUME	ESI:NOTHING

ADD_IMPORTED_SYMBOLS	ENDP

ADD__IMPS	PROC
		;
		;
		;
		MOV	EDX,FIRST__IMP__GINDEX

		TEST	EDX,EDX
		JZ	L9$

		PUSH	ESI
		MOV	ESI,EDX

PUBLIC_LOOP:
		MOV	EDX,ESI
		CONVERT	ESI,ESI,SYMBOL_GARRAY
		ASSUME	ESI:PTR SYMBOL_STRUCT
		MOV	AL,[ESI]._S_REF_FLAGS

		TEST	AL,MASK S_SPACES
		JNZ	NEXT_PUBLIC

;		TEST	AL,MASK S_REFERENCED
;		JZ	NEXT_PUBLIC

		CMP	EDI,PAGE_SIZE
		JZ	L265$
L266$:
		MOV	DPTR [EBX+EDI],EDX
		ADD	EDI,4

		TEST	ECX,ECX
		JNZ	NEXT_PUBLIC

		MOV	[ESI]._S_LAST_XREF,ECX
NEXT_PUBLIC:
		MOV	ESI,[ESI]._S_NEXT_SYM_GINDEX
TEST_PUBLIC:
		TEST	ESI,ESI
		JNZ	PUBLIC_LOOP

		POP	ESI

L9$:
		RET


L265$:
		CALL	QUICK_ANOTHER_BLOCK

		JMP	L266$

		ASSUME	ESI:NOTHING

ADD__IMPS	ENDP


QUICK_ANOTHER_BLOCK	PROC	NEAR	PRIVATE
		;
		;ES:DI:AX
		;
		MOV	EDI,QN_PTR
		CALL	GET_NEW_LOG_BLK	;CAN STAY IN FASTER MEMORY...

		MOV	[EDI],EAX
		ADD	EDI,4

		MOV	EBX,EAX
		MOV	QN_PTR,EDI

		MOV	DPTR [EDI],0
		XOR	EDI,EDI

		RET

QUICK_ANOTHER_BLOCK	ENDP


Q_SET_LEFT_BLOCK	PROC	NEAR	PRIVATE
		;
		;ESI IS SYMBOL #
		;SET ESI TO BE LEFT POINTER...
		;
		PUSH	ECX
		MOV	EAX,ESI

		SHR	EAX,PAGE_BITS-2
		MOV	ECX,QN_BUFFER_PTR

		AND	ESI,PAGE_SIZE/4-1

		SHL	ESI,2
		MOV	EAX,[ECX+EAX*4+4]

		POP	ECX
		ADD	ESI,EAX

		RET

Q_SET_LEFT_BLOCK	ENDP


Q_SET_RIGHT_BLOCK	PROC	NEAR	PRIVATE
		;
		;SET EDI TO BE RIGHT POINTER...
		;
		PUSH	ECX
		MOV	EAX,EDI

		SHR	EAX,PAGE_BITS-2
		MOV	ECX,QN_BUFFER_PTR

		AND	EDI,PAGE_SIZE/4-1

		SHL	EDI,2
		MOV	EAX,[ECX+EAX*4+4]	;LOGICAL BLOCK ADDRESS

		POP	ECX
		ADD	EDI,EAX

		RET

Q_SET_RIGHT_BLOCK	ENDP


Q_SET_MIDDLE_BLOCK	PROC	NEAR	PRIVATE
		;
		;SET ES:DI TO BE RIGHT POINTER...
		;
		MOV	EAX,ECX
		MOV	EDI,ECX

		PUSH	ECX
		MOV	ECX,QN_BUFFER_PTR

		SHR	EAX,PAGE_BITS-2
		AND	EDI,PAGE_SIZE/4-1

		SHL	EDI,2
		MOV	EAX,[ECX+EAX*4+4]	;LOGICAL BLOCK ADDRESS

		POP	ECX
		ADD	EDI,EAX

		RET

Q_SET_MIDDLE_BLOCK	ENDP


QN_SORT2	PROC	NEAR
		;
		;SORT [DS:SI] VS [ES:DI]
		;
		MOV	EAX,[ESI]
		MOV	EBX,[EDI]

		CONVERT	EAX,EAX,SYMBOL_GARRAY
		CONVERT	EBX,EBX,SYMBOL_GARRAY
		ASSUME	EAX:PTR SYMBOL_STRUCT
		ASSUME	EBX:PTR SYMBOL_STRUCT

if	fg_prot OR any_overlays
		MOV	EDX,[EAX]._S_OS2_NUMBER
		MOV	ECX,[EBX]._S_OS2_NUMBER

		CMP	ECX,EDX
		JNZ	L1$
endif

		MOV	EDX,[EAX]._S_OFFSET	;
		MOV	ECX,[EBX]._S_OFFSET

		CMP	ECX,EDX
L1$:
		JNC	L3$
		;
		;XCHG THEM
		;
		QEXCHANGE
L3$:
		RET

		ASSUME	EAX:NOTHING,EBX:NOTHING

QN_SORT2	ENDP


QAX_TO_DSSI_SYMBOL	PROC	NEAR
		;
		;
		;
		CONVERT	ESI,ESI,SYMBOL_GARRAY
		ADD	ESI,SYMBOL_STRUCT._S_NAME_TEXT
		RET

QAX_TO_DSSI_SYMBOL	ENDP


QAX_TO_ESDI_SYMBOL	PROC	NEAR
		;
		;
		;
		CONVERT	EDI,EDI,SYMBOL_GARRAY
		ADD	EDI,SYMBOL_STRUCT._S_NAME_TEXT
		RET

QAX_TO_ESDI_SYMBOL	ENDP


QA_SORT2	PROC	NEAR
		;
		;SORT [DS:SI] VS [ES:DI]
		;
		PUSHM	ESI,EDI

		MOV	ESI,[ESI]		;PT TO SYMBOL
		MOV	EDI,[EDI]		;PT TO SYMBOL

		CALL	QAX_TO_DSSI

		CALL	QAX_TO_ESDI

		MOV	ECX,-1

		CALL	QAX_COMPARE

		POPM	EDI,ESI

		JBE	L2$

		QEXCHANGE

L2$:
		RET

QA_SORT2	ENDP


QAX_COMPARE_BYTE	PROC	NEAR
		;
		;
		;
		REPE	CMPSB
		RET

QAX_COMPARE_BYTE	ENDP


QAX_COMPARE_WORD	PROC	NEAR

		REPE	CMPSW
		RET

QAX_COMPARE_WORD	ENDP


DEC_RIGHT_ESDI	PROC	NEAR	PRIVATE
		;
		;
		;
		MOV	EAX,QRIGHT_NUMBER
		SUB	EDI,4

		TEST	EAX,PAGE_SIZE/4-1
		JZ	L9$

		DEC	EAX

		MOV	QRIGHT_NUMBER,EAX

		RET

L9$:
		DEC	EAX

		MOV	QRIGHT_NUMBER,EAX
		MOV	EDI,EAX

		JMP	Q_SET_RIGHT_BLOCK

DEC_RIGHT_ESDI	ENDP


INC_LEFT_DSSI	PROC	NEAR	PRIVATE
		;
		;
		;
		MOV	EAX,QLEFT_NUMBER
		ADD	ESI,4

		INC	EAX

		MOV	QLEFT_NUMBER,EAX
		TEST	EAX,PAGE_SIZE/4-1

		JZ	L9$

		RET

L9$:
		MOV	ESI,EAX
		JMP	Q_SET_LEFT_BLOCK

INC_LEFT_DSSI	ENDP


QAX_MOVE_ASCIZ	PROC	NEAR
		;
		;
		;
		LEA	ECX,QN_SYMBOL_TEXT
		LEA	EBX,QN_SYMBOL_TEXT

		NEG	ECX
L1$:
		MOV	EAX,[ESI]
		ADD	ESI,4

		MOV	[EBX],EAX
		ADD	EBX,4

		OR	AL,AL
		JZ	L2$

		OR	AH,AH
		JZ	L3$

		TEST	EAX,000FF0000H
		JZ	L4$

		TEST	EAX,0FF000000H
		JNZ	L1$

		ADD	EBX,ECX			;LENGTH PLUS ONE ZERO...

		RET

L2$:
		LEA	EBX,[EBX+ECX-3]
		RET

L3$:
		LEA	EBX,[EBX+ECX-2]
		RET

L4$:
		LEA	EBX,[EBX+ECX-1]
		RET

QAX_MOVE_ASCIZ	ENDP



if	fg_segm

		PUBLIC	TQUICK_ENTRYNAMES

QAX_TO_DSSI_ENTRY	PROC	NEAR
		;
		;
		;
		CONVERT	ESI,ESI,ENTRYNAME_GARRAY
		ADD	ESI,ENT_STRUCT._ENT_TEXT
		RET

QAX_TO_DSSI_ENTRY	ENDP


QAX_TO_ESDI_ENTRY	PROC	NEAR
		;
		;
		;
		CONVERT	EDI,EDI,ENTRYNAME_GARRAY
		ADD	EDI,ENT_STRUCT._ENT_TEXT
		RET

QAX_TO_ESDI_ENTRY	ENDP


TQUICK_ENTRYNAMES	PROC
		;
		;
		;
		PUSHM	EBP,EDI,ESI,EBX

		MOV	EBP,ESP
                ;
                ; Adjust ESP in 4K increments
                ;
		SUB	ESP,SIZEOF QUICK_VARS - SYMBOL_TEXT_SIZE - 4
                PUSH	EBP
                SUB	ESP,SYMBOL_TEXT_SIZE/2 - 4
                PUSH	EBP
                SUB	ESP,SYMBOL_TEXT_SIZE/2 - 4
                PUSH	EBP

		MOV	QN_BUFFER_PTR,EAX
		CALL	QUICK_ENTRY_INIT

		MOV	QAX_TO_DSSI,OFF QAX_TO_DSSI_ENTRY
		MOV	QAX_TO_ESDI,OFF QAX_TO_ESDI_ENTRY
		MOV	QAX_COMPARE,OFF QAX_COMPARE_BYTE
		MOV	QAX_MOVE_TEXT,OFF QAX_MOVE_ASCIZ
		JMP	QAX_HELP_ENTRY

TQUICK_ENTRYNAMES	ENDP

endif

if	fg_pe

		PUBLIC	TQUICK_RESNAMES

QAX_MOVE_UNICODE	PROC	NEAR
		;
		;
		;
		LEA	EBX,QN_SYMBOL_TEXT
		LEA	ECX,QN_SYMBOL_TEXT+2
L1$:
		MOV	EAX,[ESI]
		ADD	ESI,4

		MOV	[EBX],EAX
		ADD	EBX,4

		TEST	EAX,00000FFFFH
		JZ	L2$

		TEST	EAX,0FFFF0000H
		JNZ	L1$

		ADD	EBX,2
L2$:
		SUB	EBX,ECX

		SHR	EBX,1

		RET

QAX_MOVE_UNICODE	ENDP


QAX_TO_DSSI_RES	PROC	NEAR
		;
		;
		;
		CONVERT	ESI,ESI,RESNAME_GARRAY
		ADD	ESI,RESNAME_STRUCT._RN_UNITEXT
		RET

QAX_TO_DSSI_RES	ENDP


QAX_TO_ESDI_RES	PROC	NEAR
		;
		;
		;
		CONVERT	EDI,EDI,RESNAME_GARRAY
		ADD	EDI,RESNAME_STRUCT._RN_UNITEXT
		RET

QAX_TO_ESDI_RES	ENDP


TQUICK_RESNAMES	PROC
		;
		;
		;
		PUSHM	EBP,EDI,ESI,EBX

		MOV	EBP,ESP
                ;
                ; Adjust ESP in 4K increments
                ;
		SUB	ESP,SIZEOF QUICK_VARS - SYMBOL_TEXT_SIZE - 4
                PUSH	EBP
                SUB	ESP,SYMBOL_TEXT_SIZE/2 - 4
                PUSH	EBP
                SUB	ESP,SYMBOL_TEXT_SIZE/2 - 4
                PUSH	EBP

		MOV	QN_BUFFER_PTR,EAX
		CALL	QUICK_RESNAMES_INIT

		MOV	QAX_TO_DSSI,OFF QAX_TO_DSSI_RES
		MOV	QAX_TO_ESDI,OFF QAX_TO_ESDI_RES
		MOV	QAX_COMPARE,OFF QAX_COMPARE_WORD
		MOV	QAX_MOVE_TEXT,OFF QAX_MOVE_UNICODE

		JMP	QAX_HELP_RES

TQUICK_RESNAMES	ENDP

endif


TQUICK_ALPHA_XREF	PROC
		;
		;
		PUSHM	EBP,EDI,ESI,EBX

		MOV	EBP,ESP
		ASSUME	EBP:PTR QUICK_VARS
                ;
                ; Adjust ESP in 4K increments
                ;
		SUB	ESP,SIZEOF QUICK_VARS - SYMBOL_TEXT_SIZE - 4
                PUSH	EBP
                SUB	ESP,SYMBOL_TEXT_SIZE/2 - 4
                PUSH	EBP
                SUB	ESP,SYMBOL_TEXT_SIZE/2 - 4
                PUSH	EBP

		MOV	QN_BUFFER_PTR,EAX
		CALL	QUICK_XREF_INIT

		JMP	QAX_HELP

TQUICK_ALPHA_XREF	ENDP


TQUICK_ALPHA	PROC
		;
		;
		;
		;OK BOYS, HERE GOES A QUICK-SORT IMPLEMENTATION...
		;
		;SI IS LEFT SYMBOL #, DI IS RIGHT SYMBOL #
		;
		PUSHM	EBP,EDI,ESI,EBX			;SAVE THAT STACK FRAME

		MOV	EBP,ESP
                ;
                ; Adjust ESP in 4K increments
                ;
		SUB	ESP,SIZEOF QUICK_VARS - SYMBOL_TEXT_SIZE - 4
                PUSH	EBP
                SUB	ESP,SYMBOL_TEXT_SIZE/2 - 4
                PUSH	EBP
                SUB	ESP,SYMBOL_TEXT_SIZE/2 - 4
                PUSH	EBP

		MOV	QN_BUFFER_PTR,EAX
		CALL	QUICK_INIT
QAX_HELP::
		MOV	QAX_TO_DSSI,OFF QAX_TO_DSSI_SYMBOL
		MOV	QAX_TO_ESDI,OFF QAX_TO_ESDI_SYMBOL
		MOV	QAX_COMPARE,OFF QAX_COMPARE_BYTE
		MOV	QAX_MOVE_TEXT,OFF QAX_MOVE_ASCIZ
QAX_HELP_ENTRY::
QAX_HELP_RES::
		CALL	QUICK_ALPH

		MOV	ESP,EBP

		POPM	EBX,ESI,EDI,EBP

		RET

TQUICK_ALPHA	ENDP


QUICK_ALPHA_1	PROC	NEAR

QA_2:
		;
		;JUST SORT THE TWO AND RETURN...
		;
		CALL	Q_SET_LEFT_BLOCK	;DS:SI
		CALL	Q_SET_RIGHT_BLOCK	;ES:DI
		JMP	QA_SORT2

QA_3:
		POP	EAX
QA_DONE:
		RET

QUICK_ALPH::
		MOV	ECX,EDI
QUICK_ALPH_1::

		SUB	ECX,ESI
		JNA	QA_DONE		;RIGHT <= LEFT, QUIT
		;
		;WHAT ABOUT REAL SMALL CX ?
		;
		INC	ECX
		JZ	QA_DONE

		CMP	ECX,2
		JZ	QA_2

		MOV	QDELTA,ECX

		SHR	ECX,1
		PUSH	ESI

		ADD	ECX,ESI		;HALF WAY IN BETWEEN...
		MOV	QRIGHT_NUMBER,EDI

		MOV	QLEFT_NUMBER,ESI
		CALL	Q_SET_LEFT_BLOCK	;DS:SI

		MOV	QLEFT_PTR,ESI
		CALL	Q_SET_RIGHT_BLOCK	;ES:DI

		MOV	QRIGHT_PTR,EDI
		CALL	Q_SET_MIDDLE_BLOCK

		MOV	QMIDDLE_PTR,EDI
		;
		;DO THREE-SOME SORT
		;
		;IF LEFT>MIDDLE, XCHG LEFT&MIDDLE
		;
		CALL	QA_SORT2
		;
		;IF LEFT > RIGHT, XCHG LEFT&RIGHT
		;
		MOV	EDI,QRIGHT_PTR
		CALL	QA_SORT2
		;
		;LASTLY, IF MIDDLE > RIGHT, XCHG MIDDLE&RIGHT
		;
		MOV	ESI,QMIDDLE_PTR
		CALL	QA_SORT2

		CMP	QDELTA,3
		JZ	QA_3

		;NOW XCHG MIDDLE WITH RIGHT-1
		;
		CALL	DEC_RIGHT_ESDI

		QEXCHANGE
		;
		;DEFINE TEST SYMBOL BY MOVING TEXT TO DGROUP
		;
		MOV	EAX,QRIGHT_NUMBER	;SAVE RIGHTY
		MOV	ESI,[EDI]		;MOVE SYMBOL TEXT TO

		PUSH	EAX

		CALL	QAX_TO_DSSI

		CALL	QAX_MOVE_TEXT

		CALL	DEC_RIGHT_ESDI

		MOV	ESI,QLEFT_PTR
		CALL	INC_LEFT_DSSI

		MOV	EAX,ESI
		MOV	QRIGHT_PTR,EDI
		;
		;SCAN FROM LEFT UNTIL SOMETHING FOUND >= DX:BX
		;
		MOV	EDX,QLEFT_NUMBER

QAL_AGAIN:
QAL_LOOP:
		MOV	EDI,[EAX]		;PT TO SYMBOL
		LEA	ESI,QN_SYMBOL_TEXT

		ADD	EAX,4
		MOV	ECX,EBX

		CALL	QAX_TO_ESDI

		CALL	QAX_COMPARE

		LEA	ECX,[EDX+1]
		JBE	QAL_TRY_RIGHT

		INC	EDX

		AND	ECX,PAGE_SIZE/4 - 1
		JNZ	QAL_LOOP

		MOV	ESI,EDX
		CALL	Q_SET_LEFT_BLOCK

		MOV	EAX,ESI
		JMP	QAL_LOOP

QAL_TRY_RIGHT:
		LEA	ECX,[EAX-4]
		MOV	EAX,QRIGHT_PTR

		MOV	QLEFT_PTR,ECX
		MOV	QLEFT_NUMBER,EDX

		MOV	EDX,QRIGHT_NUMBER
		;
		;SCAN FROM RIGHT UNTIL SOMETHING FOUND <= SYMBOL_TEXT
		;
QAR_LOOP:
		MOV	EDI,[EAX]			;PT TO SYMBOL
		LEA	ESI,QN_SYMBOL_TEXT

		SUB	EAX,4
		MOV	ECX,EBX

		CALL	QAX_TO_ESDI

		CALL	QAX_COMPARE

		MOV	ECX,EDX
		JAE	QAR_SWAP

		DEC	EDX

		AND	ECX,PAGE_SIZE/4-1
		JNZ	QAR_LOOP

		MOV	EDI,EDX
		CALL	Q_SET_RIGHT_BLOCK

		MOV	EAX,EDI
		JMP	QAR_LOOP

QAR_SWAP:
		LEA	EDI,[EAX+4]
		MOV	ESI,QLEFT_PTR

		MOV	QRIGHT_PTR,EDI
		MOV	ECX,QLEFT_NUMBER

		MOV	QRIGHT_NUMBER,EDX
		MOV	EAX,[ESI]

		CMP	ECX,EDX
		JNC	QA_DONE1

		MOV	ECX,[EDI]
		MOV	[EDI],EAX

		MOV	[ESI],ECX
		CALL	DEC_RIGHT_ESDI

		MOV	QRIGHT_PTR,EDI
		CALL	INC_LEFT_DSSI

		MOV	EDX,QLEFT_NUMBER
		MOV	ECX,QRIGHT_NUMBER

		MOV	EAX,ESI
		CMP	ECX,EDX
		JAE	QAL_AGAIN
QA_DONE1:
		;
		;SWAP R+1 WITH ORIGINAL PTR...
		;
		POP	EDI		; THIS BECOMES i

		PUSH	EDI
		CALL	Q_SET_RIGHT_BLOCK

		QEXCHANGE		;SWAP THEM...

		;DETERMINE WHICH HALF WILL BE PROCESSED...
		;
		POP	ECX		;ORIGINAL RIGHTY - WHERE MIDDLE WAS STORED
		POP	EDX		;ORIGINAL LEFT

		INC	ECX
		MOV	EAX,QRIGHT_NUMBER

		MOV	EBX,ECX
		MOV	EDI,QLEFT_NUMBER

		SUB	EAX,EDX
		SUB	EBX,EDI

		CMP	EAX,EBX
		JC	QA_DONE2
		;
		;LET SAY DO SECOND HALF FIRST
		;
		MOV	EAX,QRIGHT_NUMBER	;RIGHT TO USE THERE
		PUSH	EDX			;SAVE ORIGINAL LEFT NUMBER

		PUSH	EAX
		LEA	ESI,[EDI+1]

		MOV	EDI,ECX
		CALL	QUICK_ALPH

		POPM	EDI,ESI

		MOV	ECX,EDI
		JMP	QUICK_ALPH_1

QA_DONE2:
		;
		;LETS SAY DO FIRST HALF FIRST
		;
		INC	EDI
		MOV	ESI,EDX

		PUSH	EDI
		PUSH	ECX

		MOV	EDI,QRIGHT_NUMBER
		CALL	QUICK_ALPH

		POPM	EDI,ESI

		MOV	ECX,EDI
		JMP	QUICK_ALPH_1

QUICK_ALPHA_1	ENDP


		END

